﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


// Main JS File

// Base JS classes extensisons

String.prototype.startsWith = function(pString) {
	var vMatch = this.search(new RegExp("^" + pString));
	return (vMatch != -1);
}


// YUI objects
var Event;
var Dom;
var Cookie;
var Selector;
var History;


// JS Controllers
var gUtils = {};
var gSiteLayoutCtrl = {};
var gAjaxer = {};
var gJsonResponseHandler = {};
var gAjaxLinksCtrl = {};
var gFormsCtrl = {};
var gAccountsFormCtrl = {};
var gAcademicPlanControlCtrl = {};
var gDomReadyQueue = new Array();
var gHistoryReadyQueue = new Array();
var gAcademicPlanFormCtrl = {};
var gListProgramsPageCtrl = {};
var gDialogsCtrl = {};
var gActionsContextMenusCtrl = {};
var gProgramsControlCtrl = {};
var gListCoursesPageCtrl = {};
var gCoursesControlCtrl = {};
var gAcademicTermsControlCtrl = {};
var gManageSchedulesPageCtrl = {};
var gAcademicScheduleControlCtrl = {};


gUtils.findAllButtons = function() {
	var vButts = Dom.getElementsBy(function(pEl) {
		return (pEl.tagName == 'BUTTON' || (pEl.tagName == 'INPUT' && (pEl.type == 'submit' || pEl.type == 'button')));
	});
	return vButts;
};

/*gUtils.createDocument = function() {
var vDoc;

if (YAHOO.env.ua.ie) {
vDoc = new ActiveXObject("Microsoft.XMLDOM");
vDoc.async = false;
while (vDoc.readyState != 4) { }
}
else {
vDoc = document.implementation.createDocument("", "", null);
}

return vDoc;
};*/

gUtils.createElementFromHtml = function(pInnerHtml) {
	var vEl = document.createElement("unknown");
	var vFrag = document.createDocumentFragment();

	vEl.innerHTML = pInnerHtml;
	var vCnt = vEl.childNodes.length;
	for (var i = 0; i < vCnt; i++) {
		if (vEl.childNodes[i]) {
			if (vFrag.appendChild(vEl.childNodes[i]))
				i--;
		}
	}

	return vFrag;
};

/*gUtils.replaceChildWithMany = function(pOldChild, pNewChildren) {
alert(pOldChild);
var vParent = pOldChild.parentNode;
alert(vParent);
var vNode = vParent.replaceChild(pNewChildren[pNewChildren.length - 1], pOldChild);
var vLoopCnt = pNewChildren.length;
for (i = 0; i < vLoopCnt; i++) {
alert(vNode);
alert(pNewChildren[i]);
vParent.insertBefore(pNewChildren[i], vNode);
}
alert('wtf');
};*/


// Site Layout

gSiteLayoutCtrl.layout = null;
gSiteLayoutCtrl.menu = null;

gSiteLayoutCtrl.init = function() {
	var vTopHeight = 65;
	var vBottomHeight = 120;

	if (YAHOO.env.ua.webkit)
		vBottomHeight = 160;
	if (Dom.get('main-menu')) {
		vTopHeight = 95;
		this.menu = new YAHOO.widget.MenuBar('main-menu');
	}

	this.layout = new YAHOO.widget.Layout(document.body, {
		units: [{ position: 'top', height: vTopHeight, body: 'top' },
					{ position: 'center', body: 'middle', scroll: true },
					{ position: 'bottom', body: 'bottom', height: vBottomHeight}]
	});
};

gSiteLayoutCtrl.complete = function() {
	this.layout.render();
	if (this.menu) {
		this.menu.render();
		this.menu.show();
		new YAHOO.util.Element('main-menu').removeClass('hidden');
	}
};

// Popup Dialogs Controller

gDialogsCtrl.yDialogs = new Array();

gDialogsCtrl.create = function(pId) {
	var vEl = Dom.get(pId + 'Hider');
	vEl.parentNode.removeChild(vEl);
	document.body.appendChild(vEl);
	var yDialog = new YAHOO.widget.Dialog(pId, {
		modal: true,
		visible: false,
		fixedcenter: true,
		constraintoviewport: true,
		width: "550px",
		hideaftersubmit: false
	});
	this.yDialogs[pId] = yDialog;
};

gDialogsCtrl.open = function(pId) {
	Dom.removeClass(pId + 'Hider', 'hidden');
	this.yDialogs[pId].show();
}


// Ajax Controller

gAjaxer.postSignature = '';

gAjaxer.defautCallback = {
	success: function(o) {
		var vData;
		var vCType = o.getResponseHeader["Content-Type"];

		if (vCType.startsWith("application/json")) {
			vData = YAHOO.lang.JSON.parse(o.responseText);
		}
		else if (vCType.startsWith("application/xml")) {
			vData = o.responseXML;
		}
		else {
			vData = o.responseText;
		}

		return vData;
	},

	failure: function(o) {
		alert("default" + o.statusText);
	}
};

gAjaxer.startRequest = function(pUrl, pMethod, pCallback, pPost) {
	if (!pCallback) {
		pCallback = this.defautCallback;
	}
	if (!pPost)
		pPost = null;
	if (!pMethod)
		pMethod = 'GET';
	else if (pMethod == 'POST')
		pPost += '&__signature=' + encodeURIComponent(this.postSignature);

	YAHOO.util.Connect.asyncRequest(pMethod, pUrl, pCallback, pPost);
};


// JSON response handler
gJsonResponseHandler.handleReloadOrRedirect = function(pJson) {
	if (pJson.reload) {
		if (window.location.reload) window.location.reload(true);
		else window.history.go(0);
	}
	else if (pJson.redirect) {
		window.location.href = pJson.redirect;
	}
};

gJsonResponseHandler.handleEvaluate = function(pJson) {
	if (pJson.evaluate) {
		eval(pJson.evaluate);
	}
};

gJsonResponseHandler.handleAlert = function(pJson) {
	if (pJson.alert) {
		alert(pJson.alert);
	}
};

gJsonResponseHandler.handleAll = function(pJson) {
	this.handleReloadOrRedirect(pJson);
	this.handleEvaluate(pJson);
	this.handleAlert(pJson);
};

// Ajax links controller

gAjaxLinksCtrl.ajaxLoadingIndicatorHtml = '';

gAjaxLinksCtrl.postCallback = {
	arguments: [],
	success: function(o) {
		var vData = gAjaxer.defautCallback.success(o);
		gJsonResponseHandler.handleAll(vData);
		gFormsCtrl.enableButtons();
	},
	failure: function(o) {
		alert(o.statusText);
		gFormsCtrl.enableButtons();
	}
};

gAjaxLinksCtrl.post = function(pUrl, pPost) {
	gFormsCtrl.disbaleButtons();
	gAjaxer.startRequest(pUrl, 'POST', this.postCallback, pPost);
	return false;
};

gAjaxLinksCtrl.getCallback = {
	arguments: [],
	success: function(o) {
		var vData = gAjaxer.defautCallback.success(o);
		this.arguments[0].call(null, vData);
		gFormsCtrl.enableButtons();
	},
	failure: function(o) {
		alert(o.statusText);
		gFormsCtrl.enableButtons();
	}
};

gAjaxLinksCtrl.get = function(pUrl, pCallback) {
	this.getCallback.arguments[0] = pCallback;
	gFormsCtrl.disbaleButtons();
	gAjaxer.startRequest(pUrl, 'GET', this.getCallback);
	return false;
};

gAjaxLinksCtrl.load = function(pUrl, pLoadInto, pReplace, pCallback) {
	var vCallback = pCallback;
	var vLoadInto = pLoadInto;
	var vReplace = pReplace;
	var vLoadIntoNodes;

	if (YAHOO.lang.isString(vLoadInto)) {
		var vLoadIntoNodes = Selector.query(vLoadInto);
	}
	if (vLoadIntoNodes) {
		for (var i in vLoadIntoNodes) {
			Dom.addClass(vLoadIntoNodes[i], 'ajax-loading');
			vLoadIntoNodes[i].innerHTML = this.ajaxLoadingIndicatorHtml;
		}
	}
	else if (!YAHOO.lang.isUndefined(vLoadInto.innerHTML)) {
		Dom.addClass(vLoadInto, 'ajax-loading');
		vLoadInto.innerHTML = this.ajaxLoadingIndicatorHtml;
	}

	this.get(pUrl, function(pData) {
		var vScrptEls = new Array();
		var vResult = { replaced: new Array() };


		if (vLoadIntoNodes) {
			for (var i in vLoadIntoNodes) {
				if (vReplace) {
					var vParent = vNodes[i].parentNode;
					var vEl = vParent.replaceChild(gUtils.createElementFromHtml(pData), vLoadIntoNodes[i]);
					vScrptEls = vParent.getElementsByTagName('script');
					vResult.replaced.push(vEl);
				}
				else {
					vLoadIntoNodes[i].innerHTML = pData;
				}
				Dom.removeClass(vLoadIntoNodes[i], 'ajax-loading');
			}
		}
		else if (!YAHOO.lang.isUndefined(vLoadInto.innerHTML)) {
			if (vReplace) {
				var vParent = vLoadInto.parentNode;
				var vEl = vParent.replaceChild(gUtils.createElementFromHtml(pData), vLoadInto);
				vScrptEls = vParent.getElementsByTagName('script');
				vResult.replaced.push(vEl);
			}
			else {
				vLoadInto.innerHTML = pData;
				vScrptEls = vLoadInto.getElementsByTagName('script');
			}
			Dom.removeClass(vLoadInto, 'ajax-loading');
		}

		for (var i in vScrptEls) {
			//alert(vScrptEls[i].innerHTML);
			eval(vScrptEls[i].innerHTML);
		}

		for (var i in gDomReadyQueue) {
			eval(gDomReadyQueue[i]);
		}
		gDomReadyQueue = new Array();

		if (vCallback) vCallback.call(null, vResult);
	});
};


// Form Submission Controller

gFormsCtrl.yButtons = new Array();

gFormsCtrl.disbaleButtons = function() {
	var vButts = gUtils.findAllButtons();
	if (vButts) {
		this.lastDisabledButtons = new Array();
		for (vI in vButts) {
			if (!vButts[vI].disabled) {
				if (this.yButtons[vButts[vI].getAttribute('id')])
					this.yButtons[vButts[vI].getAttribute('id')].set('disabled', true);
				else {
					vButts[vI].disabled = true;
					new YAHOO.util.Element(vButts[vI]).addClass('disabled');
				}

				this.lastDisabledButtons.push(vButts[vI]);
			}
		}
	}
};

gFormsCtrl.enableButtons = function() {
	if (this.lastDisabledButtons) {
		for (vI in this.lastDisabledButtons) {
			if (this.yButtons[this.lastDisabledButtons[vI].getAttribute('id')])
				this.yButtons[this.lastDisabledButtons[vI].getAttribute('id')].set('disabled', false);
			else {
				this.lastDisabledButtons[vI].disabled = false;
				new YAHOO.util.Element(this.lastDisabledButtons[vI]).removeClass('disabled');
			}
		}
		this.lastDisabledButtons = new Array();
	}
};

gFormsCtrl.callback = {
	arguments: [],

	success: function(o) {
		var vData = gAjaxer.defautCallback.success(o);

		if (vData.errors) {
			var vForm = this.arguments[0];
			var vFormErrs = Dom.get(vForm.id + 'Errors');
			if (vFormErrs) {
				var yFormErrs = new YAHOO.util.Element(vFormErrs);
				vFormErrs.innerHTML = vData.errors;
				if (vFormErrs.innerHTML != "") yFormErrs.removeClass("hidden");
				else yFormErrs.addClass("hidden");
			}
		}

		gJsonResponseHandler.handleEvaluate(vData);

		if (vData.reload) {
			window.location.href = window.location.href.replace(/#.*$/, '');
			return;
		}
		else if (vData.redirect) {
			window.location.href = vData.redirect;
			return;
		}

		gFormsCtrl.enableButtons();
	},

	failure: function(o) {
		alert(o.statusText);
		gFormsCtrl.enableButtons();
	}
};

gFormsCtrl.submit = function(pEv, pForm) {
	if (pEv && window.attachEvent) pEv.returnValue = false;
	else if (pEv) pEv.preventDefault();

	YAHOO.util.Connect.setForm(pForm);
	this.callback.arguments[0] = pForm;
	this.disbaleButtons();
	Dom.get('statusMessagesWrapper').innerHTML = '';
	gAjaxer.startRequest(pForm.action, 'POST', this.callback);

	return false;
};

gFormsCtrl.makePushButton = function(pButtonId, pCallbackName) {
	var yBut = new YAHOO.widget.Button(pButtonId);
	gFormsCtrl.yButtons[pButtonId + '-button'] = yBut;
	eval(pCallbackName + "(yBut);");
	return yBut;
};

gFormsCtrl.makeSubmitButton = function(pButtonId) {
	var yBut = new YAHOO.widget.Button(pButtonId);
	gFormsCtrl.yButtons[pButtonId + '-button'] = yBut;
	return yBut;
};

gFormsCtrl.makeCancelButton = function(pButtonId, pGoTo) {
	var vUrl = pGoTo;
	var yBut = new YAHOO.widget.Button(pButtonId);
	yBut.on('click', function(o) {
		if (vUrl) {
			window.location.href = vUrl;
		}
		else
			window.history.go(-1);
	});
	gFormsCtrl.yButtons[pButtonId + '-button'] = yBut;
	return yBut;
};


// AccountsForm controller

gAccountsFormCtrl.disableEnableUserFields = function(pEvent, pRadio) {
	var vForm = pRadio.form;
	for (var i = 0; i < vForm.elements.length; i++) {
		if (vForm.elements[i].type == 'text' || vForm.elements[i].type == 'password')
			vForm.elements[i].disabled = true;
	}
	var vInd = pRadio.value;
	var vFset = vForm.getElementsByTagName('fieldset');
	if (vFset[vInd]) {
		var vInputs = vFset[vInd].getElementsByTagName('input');
		for (var i in vInputs) {
			vInputs[i].disabled = false;
		}
	}
};


// AcademicPlanControl controller

gAcademicPlanControlCtrl.initActionsSideMenu = function(pButtonId, pButtonMenu) {
	if (gFormsCtrl.yButtons[pButtonId + '-button'])
		return gFormsCtrl.yButtons[pButtonId + '-button'];

	var yBut = new YAHOO.widget.Button(pButtonId, { type: 'split', menu: pButtonMenu });
	yBut.getMenu().subscribe('click', this.onActionsSideMenuClick, { buttonId: pButtonId });
	gFormsCtrl.yButtons[pButtonId + '-button'] = yBut;

	return yBut;
};

gAcademicPlanControlCtrl.onActionsSideMenuClick = function(pStype, pArgs, pObj) {
	if (pArgs[1]) {
		var vEl = Dom.getAncestorByClassName(pObj.buttonId, 'academic-plan-control');
		switch (pArgs[1].value) {
			case '0':
				History.navigate(vEl.getAttribute('id'), 'edit');
				break;
		}
	}
};

gAcademicPlanControlCtrl.loadEditForm = function(pAcademicPlanControlEl) {
	var vUrl = pAcademicPlanControlEl.getAttribute('cPlanFormUrl');
	gAjaxLinksCtrl.load(vUrl, pAcademicPlanControlEl, false);
};

gAcademicPlanControlCtrl.reload = function(pAcademicPlanControlEl) {
	var vUrl = pAcademicPlanControlEl.getAttribute('cSelfUrl');
	gAjaxLinksCtrl.load(vUrl, pAcademicPlanControlEl, true);
};

gAcademicPlanControlCtrl.load = function(pState, pArgs) {
	var vLocationHash = window.location.hash;
	var vState = vLocationHash.substr(vLocationHash.indexOf('=') + 1);

	//alert(vState);
	var vEl = Dom.get(pArgs.controlId);

	if (vState == "edit") {
		gAcademicPlanControlCtrl.loadEditForm(vEl);
	}
	else {
		gAcademicPlanControlCtrl.reload(vEl);
	}
};

gAcademicPlanControlCtrl.registerWithHistory = function(pElId) {
	var vArgs = {};
	var vInitialState = History.getBookmarkedState(pElId) || "view";

	vArgs.controlId = pElId;
	History.register(pElId, vInitialState, function(pState, pArgs) {
		gAcademicPlanControlCtrl.load(pState, pArgs);
	}, vArgs);
};

gAcademicPlanControlCtrl.initForHistory = function(pElId) {
	var vState = History.getCurrentState(pElId);
	if (vState != "view")
		this.load(vState, { controlId: pElId });
};


// AcademicPlanForm controller

gAcademicPlanFormCtrl.removalConfirmationMessage = '';

gAcademicPlanFormCtrl.addDivision = function(pArgs) {
	var vRow1 = Dom.getAncestorByClassName(pArgs.button, 'row');
	var vRow2 = Dom.getPreviousSibling(vRow1);
	var vCell1 = Selector.query('div.field', vRow2)[0];
	var vAddedDivisionsInp = Selector.query('input[type=hidden]', vCell1)[0];
	var vHiddenChilds = Dom.getChildrenBy(vCell1, function(pNode) {
		return (Dom.hasClass(pNode, 'row') && Dom.hasClass(pNode, 'hidden'));
	});
	if (!YAHOO.lang.isUndefined(vHiddenChilds[0]) && !YAHOO.lang.isUndefined(vHiddenChilds[1])
		&& !YAHOO.lang.isUndefined(vHiddenChilds[2])) {
		var vIndexInp = Dom.getPreviousSibling(vHiddenChilds[0]);

		Dom.removeClass(vHiddenChilds[0], 'hidden');
		Dom.removeClass(vHiddenChilds[1], 'hidden');
		Dom.removeClass(vHiddenChilds[2], 'hidden');

		vCell1.removeChild(vIndexInp);
		vCell1.removeChild(vHiddenChilds[0]);
		vCell1.removeChild(vHiddenChilds[1]);
		vCell1.removeChild(vHiddenChilds[2]);

		vCell1.appendChild(vIndexInp);
		vCell1.appendChild(vHiddenChilds[0]);
		vCell1.appendChild(vHiddenChilds[1]);
		vCell1.appendChild(vHiddenChilds[2]);

		vAddedDivisionsInp.value += vIndexInp.value + ",";
		Selector.query('input', vHiddenChilds[0])[0].focus();
	}

	if (vHiddenChilds.length <= 3) {
		Dom.addClass(pArgs.button, 'hidden');
	}
};

gAcademicPlanFormCtrl.addCategory = function(pArgs) {
	var vRow1 = Dom.getAncestorByClassName(pArgs.button, 'row');
	var vRow2 = Dom.getPreviousSibling(vRow1);
	var vCell1 = Selector.query('div.field', vRow2)[0];
	var vAddedCategoriesInp = Selector.query('input[type=hidden]', vCell1)[0];
	var vHiddenChilds = Dom.getChildrenBy(vCell1, function(pNode) {
		return (Dom.hasClass(pNode, 'row') && Dom.hasClass(pNode, 'hidden'));
	});

	if (!YAHOO.lang.isUndefined(vHiddenChilds[0]) && !YAHOO.lang.isUndefined(vHiddenChilds[1])) {
		var vIndexInp = Dom.getPreviousSibling(vHiddenChilds[0]);

		Dom.removeClass(vHiddenChilds[0], 'hidden');
		Dom.removeClass(vHiddenChilds[1], 'hidden');

		vCell1.removeChild(vIndexInp);
		vCell1.removeChild(vHiddenChilds[0]);
		vCell1.removeChild(vHiddenChilds[1]);

		vCell1.appendChild(vIndexInp);
		vCell1.appendChild(vHiddenChilds[0]);
		vCell1.appendChild(vHiddenChilds[1]);

		vAddedCategoriesInp.value += vIndexInp.value + ",";
		Selector.query('input', vHiddenChilds[0])[0].focus();
	}

	if (vHiddenChilds.length <= 2) {
		Dom.addClass(pArgs.button, 'hidden');
	}
};

gAcademicPlanFormCtrl.addTerm = function(pArgs) {
	var vRow1 = Dom.getAncestorByClassName(pArgs.button, 'row');
	var vRow2 = Dom.getPreviousSibling(vRow1);
	var vCell1 = Selector.query('div.field', vRow2)[0];
	var vAddedTermsInp = Selector.query('input[type=hidden]', vCell1)[0];
	var vHiddenChilds = Dom.getChildrenBy(vCell1, function(pNode) {
		return (Dom.hasClass(pNode, 'row') && Dom.hasClass(pNode, 'hidden'));
	});

	if (!YAHOO.lang.isUndefined(vHiddenChilds[0]) && !YAHOO.lang.isUndefined(vHiddenChilds[1])) {
		var vIndexInp = Dom.getPreviousSibling(vHiddenChilds[0]);

		Dom.removeClass(vHiddenChilds[0], 'hidden');
		Dom.removeClass(vHiddenChilds[1], 'hidden');

		vCell1.removeChild(vIndexInp);
		vCell1.removeChild(vHiddenChilds[0]);
		vCell1.removeChild(vHiddenChilds[1]);

		vCell1.appendChild(vIndexInp);
		vCell1.appendChild(vHiddenChilds[0]);
		vCell1.appendChild(vHiddenChilds[1]);

		vAddedTermsInp.value += vIndexInp.value + ",";
		Selector.query('input', vHiddenChilds[0])[0].focus();
	}

	if (vHiddenChilds.length <= 2) {
		Dom.addClass(pArgs.button, 'hidden');
	}
};

gAcademicPlanFormCtrl.removeTerm = function(pEvent, pImgEl, pIsNew) {
	if (this.removalConfirmationMessage && !confirm(this.removalConfirmationMessage))
		return;

	var vRow1 = Dom.getAncestorByClassName(pImgEl, 'row');
	var vRow2 = Dom.getNextSibling(vRow1);
	var vIndexInp = Dom.getPreviousSibling(vRow1);

	if (pIsNew) {
		var vPRow = Dom.getAncestorByClassName(vRow1, 'row');
		var vAddedTermsInp = Selector.query('input[type=hidden]', vPRow)[0];
		var vAddRow = Dom.getNextSibling(vPRow);
		var vBut = Selector.query('div.cell button', vAddRow)[0];

		Dom.addClass(vRow1, 'hidden');
		Dom.addClass(vRow2, 'hidden');
		Dom.removeClass(vBut, 'hidden');
		vAddedTermsInp.value = vAddedTermsInp.value.replace(new RegExp(vIndexInp.value + ","), "");
	}
	else {
		vIndexInp.parentNode.removeChild(vIndexInp);
		vRow1.parentNode.removeChild(vRow1);
		vRow2.parentNode.removeChild(vRow2);
	}
};

gAcademicPlanControlCtrl.finishAddDivisionButton = function(yButton) {
	yButton.on('click', function(e) {
		gAcademicPlanFormCtrl.addDivision({ button: e.target });
	});
};

gAcademicPlanControlCtrl.finishAddCategoryButton = function(yButton) {
	yButton.on('click', function(e) {
		gAcademicPlanFormCtrl.addCategory({ button: e.target });
	});
};

gAcademicPlanControlCtrl.finishAddTermButton = function(yButton) {
	yButton.on('click', function(e) {
		gAcademicPlanFormCtrl.addTerm({ button: e.target });
	});
};

gAcademicPlanFormCtrl.onMouseOutRemovable = function(pEvent, pRowEl) {
	var vImg = Selector.query('div.cell>img.link', pRowEl)[0];
	if (YAHOO.lang.isUndefined(vImg))
		vImg = Selector.query('div.cell>img.link', Dom.getPreviousSibling(pRowEl))[0];

	Dom.addClass(vImg, 'hidden');
};

gAcademicPlanFormCtrl.onMouseOverRemovable = function(pEvent, pRowEl) {
	var vImg = Selector.query('div.cell>img.link', pRowEl)[0];
	if (YAHOO.lang.isUndefined(vImg))
		vImg = Selector.query('div.cell>img.link', Dom.getPreviousSibling(pRowEl))[0];

	Dom.removeClass(vImg, 'hidden');
};

gAcademicPlanFormCtrl.removeDivision = function(pEvent, pImgEl, pIsNew) {
	if (this.removalConfirmationMessage && !confirm(this.removalConfirmationMessage))
		return;

	var vRow1 = Dom.getAncestorByClassName(pImgEl, 'row');
	var vRow2 = Dom.getNextSibling(vRow1);
	var vRow3 = Dom.getNextSibling(vRow2);
	var vIndexInp = Dom.getPreviousSibling(vRow1);

	if (pIsNew) {
		var vPRow = Dom.getAncestorByClassName(vRow1, 'row');
		var vAddedDivisionsInp = Selector.query('input[type=hidden]', vPRow)[0];
		var vAddRow = Dom.getNextSibling(vPRow);
		var vBut = Selector.query('div.cell button', vAddRow);

		Dom.addClass(vRow1, 'hidden');
		Dom.addClass(vRow2, 'hidden');
		Dom.addClass(vRow3, 'hidden');
		Dom.removeClass(vBut, 'hidden');
		vAddedDivisionsInp.value = vAddedDivisionsInp.value.replace(new RegExp(vIndexInp.value + ","), "");
	}
	else {
		vIndexInp.parentNode.removeChild(vIndexInp);
		vRow1.parentNode.removeChild(vRow1);
		vRow2.parentNode.removeChild(vRow2);
		vRow3.parentNode.removeChild(vRow3);
	}
};

gAcademicPlanFormCtrl.removeCategory = function(pEvent, pImgEl, pIsNew) {
	if (this.removalConfirmationMessage && !confirm(this.removalConfirmationMessage))
		return;

	var vRow1 = Dom.getAncestorByClassName(pImgEl, 'row');
	var vRow2 = Dom.getNextSibling(vRow1);
	var vIndexInp = Dom.getPreviousSibling(vRow1);

	if (pIsNew) {
		var vPRow = Dom.getAncestorByClassName(vRow1, 'row');
		var vAddedCategoriesInp = Selector.query('input[type=hidden]', vPRow)[0];
		var vAddRow = Dom.getNextSibling(vPRow);
		var vBut = Selector.query('div.cell button', vAddRow);

		Dom.addClass(vRow1, 'hidden');
		Dom.addClass(vRow2, 'hidden');
		Dom.removeClass(vBut, 'hidden');
		vAddedCategoriesInp.value = vAddedCategoriesInp.value.replace(new RegExp(vIndexInp.value + ","), "");
	}
	else {
		vIndexInp.parentNode.removeChild(vIndexInp);
		vRow1.parentNode.removeChild(vRow1);
		vRow2.parentNode.removeChild(vRow2);
	}
};


// List Programs Page Controller

gListProgramsPageCtrl.buttonTexts = {};

gListProgramsPageCtrl.buttonTexts.submit = '';

gListProgramsPageCtrl.buttonTexts.cancel = '';

gListProgramsPageCtrl.saveProgramDialog = null;

gListProgramsPageCtrl.handleCreateProgram = function(pEvent, pLinkEl) {
	Event.preventDefault(pEvent);
	gDialogsCtrl.open('saveProgramDialog');
	gAjaxLinksCtrl.load(pLinkEl.href, this.saveProgramDialog.body, false, function(pResult) {
		var vActionRow = Dom.getElementsByClassName('action', 'div', gListProgramsPageCtrl.saveProgramDialog.body)[0];
		vActionRow.parentNode.removeChild(vActionRow);
		gListProgramsPageCtrl.saveProgramDialog.registerForm();
		gListProgramsPageCtrl.saveProgramDialog.center();
		Selector.query('input', gListProgramsPageCtrl.saveProgramDialog.body)[0].focus();
	});
	return false;
};

gListProgramsPageCtrl.handleSubmitSaveProgramDialog = function() {
	this.submit();
	return false;
};

gListProgramsPageCtrl.handleCancelSaveProgramDialog = function(pType, pArgs) {
	this.cancel();
};

gListProgramsPageCtrl.submitSaveProgramDialog = function(pType, pArgs) {
	gFormsCtrl.submit(pArgs[0], this.form);
};

gListProgramsPageCtrl.init = function() {
	this.saveProgramDialog = gDialogsCtrl.yDialogs['saveProgramDialog'];
	this.saveProgramDialog.cfg.queueProperty('buttons', [
		{ text: this.buttonTexts.submit, handler: this.handleSubmitSaveProgramDialog, isDefault: true },
		{ text: this.buttonTexts.cancel, handler: this.handleCancelSaveProgramDialog }
	]);
	this.saveProgramDialog.cfg.queueProperty('postmethod', "manual");
	this.saveProgramDialog.render();
	this.saveProgramDialog.manualSubmitEvent.subscribe(this.submitSaveProgramDialog);
};


// List Courses Page Controller

gListCoursesPageCtrl.buttonTexts = {};

gListCoursesPageCtrl.buttonTexts.submit = '';

gListCoursesPageCtrl.buttonTexts.cancel = '';

gListCoursesPageCtrl.saveCourseDialog = null;

gListCoursesPageCtrl.handleCreateCourse = function(pEvent, pLinkEl) {
	Event.preventDefault(pEvent);
	gDialogsCtrl.open('saveCourseDialog');
	gAjaxLinksCtrl.load(pLinkEl.href, this.saveCourseDialog.body, false, function(pResult) {
		var vActionRow = Dom.getElementsByClassName('action', 'div', gListCoursesPageCtrl.saveCourseDialog.body)[0];
		vActionRow.parentNode.removeChild(vActionRow);
		gListCoursesPageCtrl.saveCourseDialog.registerForm();
		gListCoursesPageCtrl.saveCourseDialog.center();
		Selector.query('input', gListCoursesPageCtrl.saveCourseDialog.body)[0].focus();
	});
	return false;
};

gListCoursesPageCtrl.handleSubmitSaveCourseDialog = function() {
	this.submit();
	return false;
};

gListCoursesPageCtrl.handleCancelSaveCourseDialog = function(pType, pArgs) {
	this.cancel();
};

gListCoursesPageCtrl.submitSaveCourseDialog = function(pType, pArgs) {
	gFormsCtrl.submit(pArgs[0], this.form);
};

gListCoursesPageCtrl.init = function() {
	this.saveCourseDialog = gDialogsCtrl.yDialogs['saveCourseDialog'];
	this.saveCourseDialog.cfg.queueProperty('buttons', [
		{ text: this.buttonTexts.submit, handler: this.handleSubmitSaveCourseDialog, isDefault: true },
		{ text: this.buttonTexts.cancel, handler: this.handleCancelSaveCourseDialog }
	]);
	this.saveCourseDialog.cfg.queueProperty('postmethod', "manual");
	this.saveCourseDialog.render();
	this.saveCourseDialog.manualSubmitEvent.subscribe(this.submitSaveCourseDialog);
};



// ProgramsControl Controller

gProgramsControlCtrl.messages = {};

gProgramsControlCtrl.messages.confirmDelete = '';

gProgramsControlCtrl.showEditProgramDialog = function(pProgramEl) {
	var yDialog = gDialogsCtrl.yDialogs['saveProgramDialog'];
	var vUrl = pProgramEl.getAttribute('cEditFormUrl');
	if (yDialog) {
		gDialogsCtrl.open('saveProgramDialog');
		gAjaxLinksCtrl.load(vUrl, yDialog.body, false, function(pResult) {
			var vActionRow = Dom.getElementsByClassName('action', 'div', yDialog.body)[0];
			vActionRow.parentNode.removeChild(vActionRow);
			yDialog.registerForm();
			yDialog.center();
			Selector.query('input', yDialog.body)[0].focus();
		});
	}
};

gProgramsControlCtrl.sendDeleteProgramRequest = function(pProgramEl) {
	var yDialog = gDialogsCtrl.yDialogs['saveProgramDialog'];
	var vUrl = pProgramEl.getAttribute('cDeleteUrl');
	if (confirm(this.messages.confirmDelete) && yDialog) {
		gAjaxLinksCtrl.post(vUrl);
	}
};

gProgramsControlCtrl.onProgramMenuClick = function(pType, pArgs, pObj) {
	var yMItem = pArgs[1];
	var vProgramEl = Dom.getAncestorByClassName(yMItem.element, 'program');
	switch (yMItem.index) {
		case 0:
			gProgramsControlCtrl.showEditProgramDialog(vProgramEl);
			break;
		case 1:
			gProgramsControlCtrl.sendDeleteProgramRequest(vProgramEl);
			break;
	}
}

gProgramsControlCtrl.initList = function(pProgramsControlId) {
	var vEl = Dom.get(pProgramsControlId);
	var vProgramEls = Selector.query('.programs-list .program', vEl);
	for (var vI in vProgramEls) {
		var vMenuEl = Selector.query('.program-header .actions-context-menu', vProgramEls[vI])[0];
		Dom.addClass(vMenuEl, 'right');
	}
};


// Context Menus Controller

gActionsContextMenusCtrl.create = function(pId, pClickHandlerName) {
	var vMenuEl = Dom.get(pId);
	var yMenuBar = new YAHOO.widget.MenuBar(vMenuEl, { autosubmenudisplay: true });
	Dom.removeClass(vMenuEl, 'hidden');
	yMenuBar.render();
	yMenuBar.getSubmenus()[0].subscribe('click', eval(pClickHandlerName));
};


// CoursesControl Controller

gCoursesControlCtrl.messages = {};

gCoursesControlCtrl.messages.confirmDelete = '';

gCoursesControlCtrl.showEditCourseDialog = function(pCourseEl) {
	var yDialog = gDialogsCtrl.yDialogs['saveCourseDialog'];
	var vUrl = pCourseEl.getAttribute('cEditFormUrl');
	if (yDialog) {
		gDialogsCtrl.open('saveCourseDialog');
		gAjaxLinksCtrl.load(vUrl, yDialog.body, false, function(pResult) {
			var vActionRow = Dom.getElementsByClassName('action', 'div', yDialog.body)[0];
			vActionRow.parentNode.removeChild(vActionRow);
			yDialog.registerForm();
			yDialog.center();
			Selector.query('input', yDialog.body)[0].focus();
		});
	}
};

gCoursesControlCtrl.sendDeleteCourseRequest = function(pCourseEl) {
	var yDialog = gDialogsCtrl.yDialogs['saveCourseDialog'];
	var vUrl = pCourseEl.getAttribute('cDeleteUrl');
	if (confirm(this.messages.confirmDelete) && yDialog) {
		gAjaxLinksCtrl.post(vUrl);
	}
};

gCoursesControlCtrl.onCourseMenuClick = function(pType, pArgs, pObj) {
	var yMItem = pArgs[1];
	var vCourseEl = Dom.getAncestorByClassName(yMItem.element, 'course');
	switch (yMItem.index) {
		case 0:
			gCoursesControlCtrl.showEditCourseDialog(vCourseEl);
			break;
		case 1:
			gCoursesControlCtrl.sendDeleteCourseRequest(vCourseEl);
			break;
	}
}

gCoursesControlCtrl.initList = function(pCoursesControlId) {
	var vEl = Dom.get(pCoursesControlId);
	var vCourseEls = Selector.query('.courses-list .course', vEl);
	for (var vI in vCourseEls) {
		var vMenuEl = Selector.query('.course-header .actions-context-menu', vCourseEls[vI])[0];
		Dom.addClass(vMenuEl, 'right');
	}
};

gCoursesControlCtrl.onSelectCoursesClick = function(pSelectCourseEl) {
	var vCoursesEl = Dom.getNextSibling(pSelectCourseEl);
	if (Dom.hasClass(vCoursesEl, 'hidden'))
		Dom.removeClass(vCoursesEl, 'hidden');
	else
		Dom.addClass(vCoursesEl, 'hidden');
};

gCoursesControlCtrl.onCourseCheckClick = function(pCourseCheckEl) {
	var vParent = Dom.getAncestorByClassName(pCourseCheckEl, 'courses');
	var vSelCoursesEl = Dom.getNextSibling(vParent);
	vSelCoursesEl.value = vSelCoursesEl.value.replace(new RegExp(pCourseCheckEl.value + ",*"), "");
	if (pCourseCheckEl.checked)
		vSelCoursesEl.value += "," + pCourseCheckEl.value + ",";
};



// AcademicTermsControl Controller

gAcademicTermsControlCtrl.onSelectAcademicTermsClick = function(pSelectTermsEl) {

	var vTermsEl = Dom.getNextSibling(pSelectTermsEl);
	if (Dom.hasClass(vTermsEl, 'hidden'))
		Dom.removeClass(vTermsEl, 'hidden');
	else
		Dom.addClass(vTermsEl, 'hidden');
};

gAcademicTermsControlCtrl.onAcademicTermCheckClick = function(pTermCheckEl) {

	var vParent = Dom.getAncestorByClassName(pTermCheckEl, 'academic-terms');
	var vSelTermsEl = Dom.getNextSibling(vParent);
	vSelTermsEl.value = vSelTermsEl.value.replace(new RegExp(pTermCheckEl.value + ",*"), "");
	if (pTermCheckEl.checked)
		vSelTermsEl.value += "," + pTermCheckEl.value + ",";
};



// Manage Schedules Page Controller

gManageSchedulesPageCtrl.messageConfirmDelete = '';

gManageSchedulesPageCtrl.buttonTexts = {};

gManageSchedulesPageCtrl.buttonTexts.submit = '';

gManageSchedulesPageCtrl.buttonTexts.cancel = '';

gManageSchedulesPageCtrl.saveScheduleDialog = null;

gManageSchedulesPageCtrl.handleCreateSchedule = function(pEvent, pLinkEl) {
	Event.preventDefault(pEvent);
	gDialogsCtrl.open('saveScheduleDialog');
	gAjaxLinksCtrl.load(pLinkEl.href, this.saveScheduleDialog.body, false, function(pResult) {
		var vActionRow = Dom.getElementsByClassName('action', 'div', gManageSchedulesPageCtrl.saveScheduleDialog.body)[0];
		vActionRow.parentNode.removeChild(vActionRow);
		gManageSchedulesPageCtrl.saveScheduleDialog.registerForm();
		gManageSchedulesPageCtrl.saveScheduleDialog.center();
		Selector.query('input', gManageSchedulesPageCtrl.saveScheduleDialog.body)[0].focus();
	});
	return false;
};

gManageSchedulesPageCtrl.handleSubmitSaveScheduleDialog = function() {
	this.submit();
	return false;
};

gManageSchedulesPageCtrl.handleCancelSaveScheduleDialog = function(pType, pArgs) {
	this.cancel();
};

gManageSchedulesPageCtrl.submitSaveScheduleDialog = function(pType, pArgs) {
	gFormsCtrl.submit(pArgs[0], this.form);
};

gManageSchedulesPageCtrl.init = function() {
	this.saveScheduleDialog = gDialogsCtrl.yDialogs['saveScheduleDialog'];
	this.saveScheduleDialog.cfg.queueProperty('buttons', [
		{ text: this.buttonTexts.submit, handler: this.handleSubmitSaveScheduleDialog, isDefault: true },
		{ text: this.buttonTexts.cancel, handler: this.handleCancelSaveScheduleDialog }
	]);
	this.saveScheduleDialog.cfg.queueProperty('postmethod', "manual");
	this.saveScheduleDialog.render();
	this.saveScheduleDialog.manualSubmitEvent.subscribe(this.submitSaveScheduleDialog);
};

gManageSchedulesPageCtrl.sendDeleteScheduleRequest = function(pScheduleEl) {
	var vUrl = pScheduleEl.getAttribute('cDeleteUrl');
	if (confirm(this.messageConfirmDelete)) {
		gAjaxLinksCtrl.post(vUrl);
	}
};

gManageSchedulesPageCtrl.onDeleteScheduleClick = function(pEvent, pLinkEl) {
	var vScheduleEl = Dom.getAncestorByClassName(pLinkEl, 'schedule');
	this.sendDeleteScheduleRequest(vScheduleEl);
};

gManageSchedulesPageCtrl.showEditScheduleDialog = function(pScheduleEl) {
	var yDialog = gDialogsCtrl.yDialogs['saveScheduleDialog'];
	var vUrl = pScheduleEl.getAttribute('cEditFormUrl');
	if (yDialog) {
		gDialogsCtrl.open('saveScheduleDialog');
		gAjaxLinksCtrl.load(vUrl, yDialog.body, false, function(pResult) {
			var vActionRow = Dom.getElementsByClassName('action', 'div', yDialog.body)[0];
			vActionRow.parentNode.removeChild(vActionRow);
			yDialog.registerForm();
			yDialog.center();
			Selector.query('input', yDialog.body)[0].focus();
		});
	}
};

gManageSchedulesPageCtrl.showSchedule = function(pScheduleEl) {
	var vUrl = pScheduleEl.getAttribute('cControlUrl');
	gAjaxLinksCtrl.load(vUrl, Dom.get('scheduleControlHolder'), false, function(pResult) {
		Dom.removeClass(Selector.query('.schedule-name', pScheduleEl.parentNode), 'strong');
		Dom.addClass(Selector.query('.schedule-name', pScheduleEl)[0], 'strong');
	});
};

gManageSchedulesPageCtrl.onEditScheduleClick = function(pEvent, pLinkEl) {
	var vScheduleEl = Dom.getAncestorByClassName(pLinkEl, 'schedule');
	this.showEditScheduleDialog(vScheduleEl);
};

gManageSchedulesPageCtrl.onScheduleClick = function(pEvent, pLinkEl) {
	var vScheduleEl = Dom.getAncestorByClassName(pLinkEl, 'schedule');
	this.showSchedule(vScheduleEl);
};


// AcademicScheduleControl Controller

gAcademicScheduleControlCtrl.originalCourseSlots = new Array();

gAcademicScheduleControlCtrl.yDDs = new Array();

gAcademicScheduleControlCtrl.yDDTargets = new Array();

gAcademicScheduleControlCtrl.DDProto = {};

gAcademicScheduleControlCtrl.isCourseElPrerequisitesMet = function(pCourseEl, pRowEl) {
	var vRowEl;
	var vPrereqs = pCourseEl.getAttribute('cPrequisiteIds');

	if (vPrereqs == '') return true;

	vRowEl = Dom.getPreviousSibling(pRowEl);
	while (vRowEl != null) {
		var vCourseEls = Selector.query('.course', vRowEl);
		for (var i in vCourseEls) {
			var vRegex = new RegExp(vCourseEls[i].getAttribute('cId') + ",*");
			vPrereqs = vPrereqs.replace(vRegex, "");
			if (vPrereqs == '')
				return true;
		}
		if (vPrereqs == '')
			return true;
			
		vRowEl = Dom.getPreviousSibling(vRowEl);
	}

	return vPrereqs == '';
};

gAcademicScheduleControlCtrl.isCourseElOfferedIn = function(pCourseEl, pRowEl) {
	var vTerm = Selector.query('.registration-period', pRowEl)[0].getAttribute('cTermId');
	var vTerms = pCourseEl.getAttribute('cCommonTermIds');

	return vTerms == '' ? true : vTerms.search(new RegExp(vTerm + ",")) != -1;
};

gAcademicScheduleControlCtrl.getTargettedRowClass = function(pRowEl, pDDEl) {
	var rClass = 'dd-acceptable';

	if (!this.isCourseElPrerequisitesMet(pDDEl, pRowEl)) {
		rClass = 'dd-missing-prequisites';
	}
	else if (!this.isCourseElOfferedIn(pDDEl, pRowEl)) {
		rClass = 'dd-not-commonly-offered-in';
	}

	return rClass;
};

gAcademicScheduleControlCtrl.DDProto.startDrag = function(pX, pY) {
	var vRealEl = this.getEl();
	var vProxyEl = this.getDragEl();
	var vTargetEls = YAHOO.util.DDM.getRelated(this, true);

	vProxyEl.innerHTML = vRealEl.innerHTML;
	vProxyEl.className = vRealEl.className;
	Dom.setStyle(vRealEl, "opacity", 0.1);
	for (var i in vTargetEls) {
		var vEl = vTargetEls[i].getEl();
		var vRowEl = vEl.parentNode ? vEl.parentNode.parentNode : null;
		if (vRowEl && vRowEl.tagName == 'TR') {
			Dom.addClass(vRowEl, gAcademicScheduleControlCtrl.getTargettedRowClass(vRowEl, vRealEl));
		}
	}
};

gAcademicScheduleControlCtrl.DDProto.endDrag = function(pEv) {
	YAHOO.util.Dom.setStyle(this.getEl(), "opacity", 1);
	var vTargetEls = YAHOO.util.DDM.getRelated(this, true);
	for (var i in vTargetEls) {
		var vEl = vTargetEls[i].getEl();
		var vRowEl = vEl.parentNode ? vEl.parentNode.parentNode : null;
		if (vRowEl && vRowEl.tagName == 'TR') {
			Dom.removeClass(vRowEl, 'dd-acceptable');
			Dom.removeClass(vRowEl, 'dd-missing-prequisites');
			Dom.removeClass(vRowEl, 'dd-not-commonly-offered-in');
		}
	}
};

gAcademicScheduleControlCtrl.addCourseCategoryColumn = function(pTableEl, pCatName, pCatId) {
	var vControlId = Dom.getAncestorByClassName(pTableEl, 'academic-schedule-control').getAttribute('id');
	var vIndex = -1;

	for (var i in pTableEl.rows) {
		if (!pTableEl.rows[i].cells)
			continue;

		vIndex = pTableEl.rows[i].cells.length - 1;
		if (i == 0) {
			var vNewCell = document.createElement('th');

			vNewCell.innerHTML = pCatName;
			pTableEl.rows[0].insertBefore(vNewCell, pTableEl.rows[0].cells[vIndex]);
			continue;
		}

		var vRegPeriodEl = Selector.query('.registration-period', pTableEl.rows[i])[0];
		var vId = vControlId + "RegistrationSlotT" + vRegPeriodEl.getAttribute('cTermId') +
						"Y" + vRegPeriodEl.getAttribute('cYear') + "C" + pCatId;
		var vHtml = '<div class="registration-slot" id="' + vId + '">' + "\n" + '&nbsp;' + "\n" + '</div>';
		var vNewCell = document.createElement('td');

		vNewCell.innerHTML = vHtml;
		pTableEl.rows[i].insertBefore(vNewCell, pTableEl.rows[i].cells[vIndex]);
		
		var vDDTarget = new YAHOO.util.DDTarget(vId, vControlId + 'RegistrationsDDGroup');
		gAcademicScheduleControlCtrl.yDDTargets[vId] = vDDTarget;
	}
};

gAcademicScheduleControlCtrl.getDropRegistrationSlot = function(pCourseEl, pRowEl) {
	var vCatName = pCourseEl.getAttribute('cCategoryName');
	var vCatId = pCourseEl.getAttribute('cCategoryId');
	var vTableEl = pRowEl.parentNode;
	var vIndex = -1;
	var vColIndex = -1;
	var vCatHeaderCell = Dom.getChildrenBy(Dom.getFirstChild(vTableEl), function(pNode) {
		vIndex++;
		if (YAHOO.lang.trim(pNode.innerHTML) == vCatName) {
			vColIndex = vIndex;
			return true;
		}
		return false;
	})[0];
	var rEl;

	if (vCatHeaderCell) {
		rEl = Dom.getFirstChild(pRowEl.cells[vColIndex]);
	}
	else {
		this.addCourseCategoryColumn(vTableEl, vCatName, vCatId);
		rEl = Dom.getFirstChild(pRowEl.cells[pRowEl.cells.length - 2]);
	}

	return rEl;
};

gAcademicScheduleControlCtrl.DDProto.onDragDrop = function(pEv, pId) {
	var vEl = this.getEl();

	if ("string" == typeof pId) {
		vTargetEl = YAHOO.util.DDM.getDDById(pId).getEl();
	} else {
		vTargetEl = YAHOO.util.DDM.getBestMatch(pId).getEl();
	}

	var vRowEl = vTargetEl.parentNode.parentNode;
	if (vRowEl.tagName == 'TR') {
		if (!Dom.hasClass(vRowEl, 'dd-missing-prequisites')) {
			var vDropEl = gAcademicScheduleControlCtrl.getDropRegistrationSlot(vEl, vRowEl);

			//if (Dom.hasClass(vEl.parentNode, 'course-slot'))
				//gAcademicScheduleControlCtrl.originalCourseSlots[vEl.getAttribute('id')] = vEl.parentNode;

			vEl.parentNode.removeChild(vEl);
			vDropEl.appendChild(vEl);
			vEl.style.position = '';
			vEl.style.top = '';
			vEl.style.left = '';
			Dom.removeClass(Selector.query('.remove-course-link', vEl)[0], 'hidden');
		}
	}
};

gAcademicScheduleControlCtrl.removeCourseCategoryColumn = function(pTableEl, pCatName) {
	var vIndex = -1;
	var vColIndex = -1;
	var vCatHeaderCell = Dom.getChildrenBy(Dom.getFirstChild(pTableEl), function(pNode) {
		vIndex++;
		if (YAHOO.lang.trim(pNode.innerHTML) == pCatName) {
			vColIndex = vIndex;
			return true;
		}
		return false;
	})[0];

	for (var i in pTableEl.rows) {
		if (!pTableEl.rows[i].cells)
			continue;

		pTableEl.rows[i].removeChild(pTableEl.rows[i].cells[vColIndex]);
	}
};

gAcademicScheduleControlCtrl.adjustCourseCategoryColumn = function(pTableEl, pCatId, pCatName) {
	var vControlId = Dom.getAncestorByClassName(pTableEl, 'academic-schedule-control').getAttribute('id');
	var vColIsNotEmtpy = false;

	for (var i in pTableEl.rows) {
		if (i == 0) {
			continue;
		}
		//		if (!pTableEl.rows[i].cells)
		//			continue;

		var vRegPeriodEl = Selector.query('.registration-period', pTableEl.rows[i])[0];
		if (!vRegPeriodEl)
			continue;

		var vId = vControlId + "RegistrationSlotT" + vRegPeriodEl.getAttribute('cTermId') +
						"Y" + vRegPeriodEl.getAttribute('cYear') + "C" + pCatId;
		var vEls = Dom.getChildrenBy(pTableEl.rows[i], function(pNode) {
			var vChild = Dom.getFirstChild(pNode);
			return vChild.getAttribute('id') == vId && YAHOO.lang.trim(vChild.innerHTML) != '&nbsp;' && YAHOO.lang.trim(vChild.innerHTML) != '';
		});
		if (vEls.length > 0) {
			vColIsNotEmtpy = true;
			break;
		}
	}

	if (!vColIsNotEmtpy)
		this.removeCourseCategoryColumn(pTableEl, pCatName);
};

gAcademicScheduleControlCtrl.removeCourse = function(pCourseEl) {
	var vOriginalSlot = gAcademicScheduleControlCtrl.originalCourseSlots[pCourseEl.getAttribute('id')];

	if (vOriginalSlot && vOriginalSlot != pCourseEl.parentNode) {
		var vTableEl = pCourseEl.parentNode.parentNode.parentNode.parentNode;

		pCourseEl.parentNode.removeChild(pCourseEl);
		vOriginalSlot.appendChild(pCourseEl);
		Dom.addClass(Selector.query('.remove-course-link', pCourseEl)[0], 'hidden');
		this.adjustCourseCategoryColumn(vTableEl, pCourseEl.getAttribute('cCategoryId'),
										pCourseEl.getAttribute('cCategoryName'));
	}
};

gAcademicScheduleControlCtrl.onRemoveCourseClick = function(pEv, pImgEl) {
	var vCourseEl = Dom.getAncestorByClassName(pImgEl, 'course');
	this.removeCourse(vCourseEl);
};

gAcademicScheduleControlCtrl.init = function(pId) {
	var vControlEl = Dom.get(pId);
	var vCourseEls = Selector.query('.course', vControlEl);
	//var vCourseSlotEls = Selector.query('.courses .course-slot', vControlEl);
	var vRegisrationSlotEls = Selector.query('.registrations .registration-slot', vControlEl);
	var vCourseInfoTippers = Selector.query('.course .course-info-tipper', vControlEl);
	
	for (var i in vCourseEls) {
		var vDD = new YAHOO.util.DDProxy(vCourseEls[i].getAttribute('id'), pId + 'RegistrationsDDGroup');
		var vSlotElId = pId + "CourseSlot" + vCourseEls[i].getAttribute('cId')
		var vSlotEl = Dom.get(vSlotElId);

		vDD.addToGroup(pId + 'CoursesDDGroup' + vCourseEls[i].getAttribute('id'));
		vDD.startDrag = this.DDProto.startDrag;
		vDD.endDrag = this.DDProto.endDrag;
		vDD.onDragDrop = this.DDProto.onDragDrop;
		//vDD.isTarget = false;
		gAcademicScheduleControlCtrl.yDDs[vCourseEls[i].getAttribute('id')] = vDD;
		if (vSlotEl)
			gAcademicScheduleControlCtrl.originalCourseSlots[vCourseEls[i].getAttribute('id')] = vSlotEl;
	}
	for (var i in vRegisrationSlotEls) {
		var vDDTarget = new YAHOO.util.DDTarget(vRegisrationSlotEls[i].getAttribute('id'), pId + 'RegistrationsDDGroup');
		gAcademicScheduleControlCtrl.yDDTargets[vRegisrationSlotEls[i].getAttribute('id')] = vDDTarget;
	}
	for (var i in vCourseInfoTippers) {
		var vToolTip = new YAHOO.widget.Tooltip(Dom.generateId(), {
			context: vCourseInfoTippers[i],
			text: vCourseInfoTippers[i].getAttribute('cTip')
		});
		Dom.addClass(vToolTip.element, 'yui-skin-sam');
	}
};

gAcademicScheduleControlCtrl.getSaveXML = function(pScheduleControlEl) {
	var rXml = '<?xml version="1.0" ?>';
	var vTableEl = Selector.query('.academic-schedule-control-bd .registrations table', pScheduleControlEl)[0];
	var vRegPeriodEl;
	var vYear;
	var vTerm;
	var vRegistrationEls;
	var vCourseEls;

	rXml += "\n";
	rXml += '<academic-schedule-registration-list>';

	rXml += "\n\t";
	rXml += '<period-list>';

	for (var i in vTableEl.rows) {
		if (i == 0) {
			continue;
		}

		vRegPeriodEl = Selector.query('.registration-period', vTableEl.rows[i])[0];
		if (!vRegPeriodEl)
			continue;
		
		rXml += "\n\t\t";
		rXml += '<period>';
		vRegistrationEls = Selector.query('.registration-slot', vTableEl.rows[i]);
		rXml += "\n\t\t\t";
		rXml += '<course-list>';

		for (var j in vRegistrationEls) {
			vCourseEls = Selector.query('.course', vRegistrationEls[j]);
			for (var k in vCourseEls) {
				rXml += "\n\t\t\t\t";
				rXml += '<course id="' + vCourseEls[k].getAttribute('cId') + '" />';
			}
		}

		rXml += "\n\t\t\t";
		rXml += '</course-list>';
		rXml += "\n\t\t";
		rXml += '</period>';
	}

	rXml += "\n\t";
	rXml += '</period-list>';

	rXml += "\n";
	rXml += '</academic-schedule-registration-list>';
	rXml += "\n";
	
	return rXml;
};

gAcademicScheduleControlCtrl.sendSaveAcademicSchedule = function(pScheduleControlEl) {
	var vUrl = pScheduleControlEl.getAttribute('cSaveUrl');
	var vPost = "Registrations=" + encodeURIComponent(this.getSaveXML(pScheduleControlEl));

	gAjaxLinksCtrl.post(vUrl, vPost);
};

gAcademicScheduleControlCtrl.reloadAcademicScheduleControl = function(pScheduleControlEl) {
	var vUrl = pScheduleControlEl.getAttribute('cSelfUrl');
	gAjaxLinksCtrl.load(vUrl, pScheduleControlEl, true);
};

gAcademicScheduleControlCtrl.finishSaveButton = function(yButton) {
	yButton.on('click', function(e) {
		var vEl = Dom.getAncestorByClassName(e.target, 'academic-schedule-control');
		gAcademicScheduleControlCtrl.sendSaveAcademicSchedule(vEl);
	});
};

gAcademicScheduleControlCtrl.finishReloadButton = function(yButton) {
	yButton.on('click', function(e) {
		var vEl = Dom.getAncestorByClassName(e.target, 'academic-schedule-control');
		gAcademicScheduleControlCtrl.reloadAcademicScheduleControl(vEl);
	});
};



// Load YUI components: 
(function() {
	var gLoader = new YAHOO.util.YUILoader({
		base: "http://ajax.googleapis.com/ajax/libs/yui/2.8.0r4/",
		require: ["connection", "event", "layout", "dom", "element", "json", "cookie", "menu", "button", "selector", "history", "container", "dragdrop"],
		combine: true,
		onFailure: function() {
			alert('Serious problem');
		},
		onTimeout: function() {
			alert('Very serious problem');
		},
		onSuccess: function() {
			Event = YAHOO.util.Event;
			Dom = YAHOO.util.Dom;
			Cookie = YAHOO.util.Cookie;
			Selector = YAHOO.util.Selector;
			History = YAHOO.util.History;

			History.onReady(function() {
				for (var i in gHistoryReadyQueue) {
					eval(gHistoryReadyQueue[i]);
				}
				gHistoryReadyQueue = new Array();
			});

			var vDomReady = function() {
				gSiteLayoutCtrl.init();
				gSiteLayoutCtrl.complete();
				for (var i in gDomReadyQueue) {
					eval(gDomReadyQueue[i]);
				}
				gDomReadyQueue = new Array();
				try {
					History.initialize("yui-history-field", "yui-history-iframe");
				}
				catch (e) {
					for (var i in gHistoryReadyQueue) {
						eval(gHistoryReadyQueue[i]);
					}
					gHistoryReadyQueue = new Array();
				}
			};

			if (YAHOO.env.ua.gecko) {
				Event.onDOMReady(function() {
					Event.addListener(window, 'load', function() {
						vDomReady.call();
					});
				});
			}
			else {
				Event.onDOMReady(function() {
					vDomReady.call();
				});
			}
		}
	});

	gLoader.insert();
})();